# -*-coding:utf-8-*-
# file_path = r"G:\projects\python-projicts\abq-parameter-analysis-framework\examples\test\py2_socket_test.py"
# execfile(file_path, __main__.__dict__)
import io
import os
import socket
import json
import sys
import threading


def start_server(pid=None):
    """启动TCP服务端并返回绑定的端口号

    Args:
        pid (int, optional): 进程ID。如果未提供，则从标准输入读取。
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('', 0))  # 绑定随机端口
    port = sock.getsockname()[1]
    sock.listen(1)
    file_print("[server] Server started, listening on port {}...".format(port))
    # 如果未提供pid，则从标准输入读取
    if pid is None:
        data = sys.stdin.readline().strip()
        message = json.loads(data)
        pid = message["pid"]

    # 创建包含进程ID的文件名
    filename = "socket_info_process_{}.json".format(pid)

    # 创建要写入的套接字信息
    socket_info = {
        "port": port,
        "pid": pid
    }
    # 将套接字信息写入文件（JSON格式）
    with open(filename, "w") as f:
        json.dump(socket_info, f)
    file_print("[subroutine] Socket information written to file: {} Content: {}".format(filename, socket_info))
    try:
        while True:
            conn, addr = sock.accept()
            file_print("[server] New connection from {}".format(addr))
            client_thread = threading.Thread(target=handle_client, args=(conn,))
            client_thread.start()
    except KeyboardInterrupt:
        file_print("[server] Server shutting down.")
    finally:
        sock.close()


def handle_client(conn):
    try:
        while True:
            recv_data = conn.recv(1024)
            if not recv_data:  # 客户端关闭连接
                file_print("[server] Client closed connection.")
                break
            file_print("[subroutine] Received data: {}".format(recv_data))
            try:
                # Python 2 中 recv_data 已经是字节串，不需要 decode
                header = json.loads(recv_data)
            except ValueError as e:  # Python 2 中捕获 ValueError
                file_print("[server] JSON decode error: {}".format(e))
                conn.send("ERROR: Invalid JSON")
                continue
            # 验证模块
            if not check_auth(header.get('auth', '')):
                conn.send("AUTH_FAILED")
                break
            # 处理数据类型
            if header['type'] == 'stream':
                handle_stream(conn, header['data'])
            else:
                handle_normal(conn, header['data'])
    except socket.error:
        file_print("[server] Connection reset by client.")
    finally:
        conn.close()
        file_print("[server] Connection closed.")




config = {"username": "admin", "password": "123"}


def check_auth(auth_info):
    # 从配置文件读取验证信息（需实现配置文件读取逻辑）
    return (auth_info['username'] == config['username'] and
            auth_info['password'] == config['password'])


def handle_stream(conn, init_params):
    # 初始化生成器
    gen = data_generator(init_params)

    try:
        while True:
            data = next(gen)
            conn.sendall(data.encode('utf-8'))
            file_print("[subroutine] Send data :{}".format(data))
    except StopIteration:
        conn.sendall(b"STREAM_END")
        file_print("[subroutine] Send data :{}".format("STREAM_END"))


def data_generator(init_params):
    for i in range(int(init_params)):
        yield "generator message :{}".format(i)


def handle_normal(conn, init_params):
    send_message = "process message :{}".format(init_params)
    conn.sendall(send_message.encode('utf-8'))
    file_print("[subroutine] Send data :{}".format(send_message))


def file_print(content):
    print(content)
    with io.open("print_py2.txt", "a", encoding="utf-8") as file:
        file.write((unicode(content + "\n", "utf-8")))


if __name__ == "__main__":
    file_print("---------------------------------start----------------------------------")
    file_print("current_pid:{}".format(os.getpid()))
    # try:
    # pid=None
    # pid = os.getpid()
    pid = None
    start_server(pid)
    # except Exception as e:
    #     file_print(str(e))
    #     file_print("Exception details:")
    #     file_print(traceback.format_exc())
    #     raise e
